<template>
  <n-card :header-style="{ padding: '10px', background: '#F1F5FF', marginBottom: '10px' }" ref="elementRef">
    <template #header>{{ index }}.创意内容</template>
    <n-empty description="请先选择创意模版" v-if="(!creativor.canuse || creativor.loading)">
    </n-empty>
    <n-skeleton :repeat="4" text v-if="creativor.loading || creativor.contentLoading"></n-skeleton>
    <div v-show="(!creativor.loading && !creativor.contentLoading) && creativor.canuse">
      <x-form ref="formRef" v-model:model="creativor" label-placement="left" label-width="140" :rules="rules">
        <BrandComponent :key="marketComponents['brand'] ? marketComponents['brand'].uuid : 1"
          :component="marketComponents['brand']" :params="uploadParams" v-if="marketComponents['brand']"
          :path="['creativor', 'component', 'brand']">
        </BrandComponent>
        <div class="mt-10" v-if="creativor.groups.length && adv.auth.mode == 'CREATE_ADV'">
          <span class="link-color cursor-pointer" @click="handleShow">批量添加素材</span>
        </div>
        <div class="mt-10" v-if="creativor.groups.length">

          <n-tabs @close="removeCreativeGroup" type="card" @update-value="changeCreativeGroup"
            v-if="adv.auth.mode === 'CREATE_ADV'" :closable="creativor.groups.length > 1" tab-style="min-width: 80px;"
            v-model:value="currentCreativeGroupIndex">
            <n-tab-pane v-for="(group, i) in creativor.groups" :key="group.uuid" :tab="`创意组${i+1}`" :name="i">
            </n-tab-pane>
            <template #suffix>
              <span class="link-color cursor-pointer" @click="addCreativeGroup">添加</span>
            </template>
          </n-tabs>
          <n-tabs :closable="currentCreativeGroup.creative.length > 1" type="card" :bar-width="80"
            tab-style="min-width: 80px;" size="small" v-model:value="currentCreativeIndex"
            @update-value="changeCreative" @close="removeCreative">
            <n-tab-pane v-for="(creative, i) in (currentCreativeGroup.creative || [])" :key="creative.uuid"
              :tab="`创意${i+1}`" :name="i">
            </n-tab-pane>
            <template #suffix>
              <span class="link-color cursor-pointer" quaternary type="info" @click="addCreative">添加</span>
            </template>
          </n-tabs>
          <div class="creative-container">
            <div v-if="creativor.unSpecifiedForm" class="mb-10">
              <div class="text-right mb-10">

                <n-switch size="small" v-model:value="currentCreative.derivedCreativeSwitch" :checked-value="1"
                :unchecked-value="0"></n-switch> <span class="link-color">AICG素材推荐</span>
              </div>
              <will-media :component="currentCreative.libMedia" :params="{}"></will-media>
            </div>
            <div v-else>
              <div class="mt-10" v-for="(component, ci) in (currentCreative ? currentCreative.mediaComponent : [])">
                <div class="flex items-center">
                  <div class="flex-1">
                    <MediaComponent v-if="component.componentName === 'media'" :component="component"
                      :params="uploadParams" @finish="validateComponent(component, 'media')">
                    </MediaComponent>
                    <MediaGroup :component="component" :params="uploadParams"
                      v-if="component.componentName === 'mediaGroup'" @finish="validateComponent(component, 'media')">
                    </MediaGroup>
                    <MediaShowcaseComponent @finish="validateComponent(component, 'media')"
                      v-if="component.componentName === 'mediaShowcase'" :params="uploadParams" :component="component">
                    </MediaShowcaseComponent>
                  </div>
                  <n-icon size="14" v-if="currentCreative.mediaComponent.length > 1" @click="removeGroup(ci)"
                    style="margin-left: 10px;">
                    <MinusCircleFilled></MinusCircleFilled>
                  </n-icon>
                </div>

                <div class="animate-feedback--error" v-if="feedback.media === 'error'">请上传创意资源!</div>
              </div>
              <div v-if="creativor.isComponentCreative" class="mt-10">
                <n-button style="width: 100%;" dashed @click="addGroup" :disabled="remainAddMediaNum <= 0">还可以添加{{
                  remainAddMediaNum }}组</n-button>
              </div>
            </div>
            <div class="mt-10" v-if="currentCreative.textComponent">
              <div class="component-label">创意文案</div>
              <div class="margin-top: -10px">
                <div class="flex" v-for="(component, ci) in currentCreative.textComponent">
                  <text-component class="mt-10 flex-1" :component="component"
                    @change="validateComponent(component, 'text')"
                    :path="['creativor', 'groups', currentCreativeGroupIndex, 'creative', currentCreativeIndex, 'textComponent', ci]"></text-component>
                  <n-icon size="14" v-if="currentCreative.textComponent.length > 1" @click="removeTexGroup(ci)"
                    style="margin-left: 10px;">
                    <MinusCircleFilled></MinusCircleFilled>
                  </n-icon>
                </div>
                <div class="animate-feedback--error" v-if="feedback.text === 'error'">请输入创意文案!</div>
              </div>
            </div>
            <div v-if="creativor.isComponentCreative" class="mt-10">
              <n-button style="width: 100%;" dashed @click="addTextGroup" :disabled="remainAddTextNum <= 0">还可以添加{{
                remainAddTextNum }}组</n-button>
            </div>



          </div>
        </div>
      </x-form>
    </div>
  </n-card>


  <n-modal :mask-closable="false" v-model:show="modal.show" preset="card" :title="modal.title" :bordered="false"
    :style="{ width: '1280px' }">
    <div class="mb-10">
      <n-radio-group size="tiny" v-model:value="modal.materia_index" v-if="modal.materia_form.length > 1">
        <n-radio-button size="tiny" v-for="(item, i) in modal.materia_form" :key="i" :value="i">{{ item.name
          }}</n-radio-button>
      </n-radio-group>
      <!-- materia_form -->
    </div>
    <div class="helper-tool creative-content-material-upload-containter">
      <div class="flex items-center">
        <n-upload :accept="accept" :max="materialUploadMax" :show-file-list="false" :with-credentials="true"
          :custom-request="customRequest" :multiple="true" :headers="headers" ref="uploadRef" style="width: 100%;"
          class="">
          <div style="text-align: center;width: 100%;">
            <div style="margin-bottom: 0px">
              <n-icon size="48" :depth="3">
                <archive-icon />
              </n-icon>
            </div>
            <n-p depth="3" style="margin: 3px 0 0 0">
              点击此处上传素材
            </n-p>
            <n-p depth="3">
              {{ rulesTips }}
            </n-p>
          </div>
        </n-upload>
      </div>
      <n-divider />
      <div class="flex text-helper" style="font-size: 13px;">
        <span class="mr-8">
          已选择
          <span class="warn-color">{{ modalMaterialNum }}</span>个素材,需要生成</span>
        <n-input-number :bordered="false" placeholder="" style="width: 80px" size="tiny"
          v-model:value="modal.creativeGroupNum"></n-input-number>
        <span class="ml-8 mr-8">个创意组，每个创意组中</span>
        <n-input-number :bordered="false" placeholder="" v-model:value="modal.creativeNum" style="width: 80px"
          size="tiny"></n-input-number>
        <!-- 组件化创意 -->
        <!-- mediaItemNumRange == 1 ? modal.materia_form[modal.materia_index].min :
            mediaItemNumRange -->
        <template v-if="creativor.isComponentCreative">
          <span class="ml-8 mr-8">个创意，每个创意中</span>
          <n-input-number :bordered="false" placeholder="" v-model:value="modal.materialNum" style="width: 80px"
            size="tiny" :max="15"></n-input-number>
          <span class="ml-8">个素材，每个创意中的素材上限为15个</span>
        </template>

        <!--  -->
        <span class="warn-color">(多创意组时素材将会根据顺序依次轮流生成)</span>

      </div>
    </div>
    <n-scrollbar x-scrollable class="modal-image-group">
      <div style="white-space: nowrap; padding: 12px;display: flex;">
        <div @click="selectMaterial(item)" v-for="(item, i) in currentMaterials" style="width: 200px;"
          :class="['modal-image-card', item.select ? '--active' : '', item.loading ? '--loading' : '']">
          <f-media class="image" :loading="item.loading" :media_url="item.media_url" :meta_type="item.meta_type"
            style="font-size: 0;"></f-media>
          <div class="desc">素材{{ i + 1 }}</div>
          <span class="icon-select" v-if="item.select">
            <n-icon color="#fff" size="14" :component="CheckOutlined" />
          </span>
        </div>
      </div>
    </n-scrollbar>
    <template #footer>
      <div class="text-right">
        <n-button @click="updateCreateGroup" type="primary">确定</n-button>
      </div>
    </template>

  </n-modal>

</template>



<script setup lang="ts">
import { computed, onBeforeMount, reactive, ref, toRefs, watch, defineExpose, unref } from 'vue';
import { useMessage, NEmpty, NSwitch, NUpload, NText, NCard, NModal, NDivider, NIcon, NP, NSelect, NSpin, NTag, NRadioGroup, NRadioButton, NButton, NInputNumber, NTabs, NTabPane, NImage, NScrollbar, NSkeleton, UploadCustomRequestOptions } from 'naive-ui';
import { XForm, XButton, XDataTable } from '@/components';
import { CloseOutlined, CheckOutlined, CloudUploadOutlined as ArchiveIcon, MinusCircleFilled } from '@vicons/antd';
import { useStore } from '@/store';
// media Update Code ok
import MediaGroup from './components/media-group-component.vue';
import TextComponent from './components/text-component.vue';
import http from '@/utils/http/axios'

import MediaSingleComponent from '@/store/modules/adv/component/media/single';
import WillMedia from './components/will-media.vue';
import UploadComponent from './components/upload.vue';
import MediaShowcaseComponent from './components/media-showcase.vue';
import FMedia from './components/f-media.vue'
import BrandComponent from './components/brand-component.vue';
import MediaComponent from './components/media-component.vue';
import { useUpload } from './hooks/useUpload';

defineProps({
  index: {
    type: Number
  }
})


const message = useMessage();
const store = useStore();
const adv = computed(() => store.state.adv.modal);
const loading = ref(false);
const marketComponents = computed(() => store.state.adv.modal.marketComponents);
const market = computed(() => store.state.adv.modal.market);
const creativor = computed(() => store.state.adv.modal.creativor);
const account = computed(() => {
  const accounts = store.state.adv.accounts;
  return accounts[0];
})
const rules = reactive({

});


const uploadModal = reactive<any>({
  show: false,
  uploadRules: {
    textMaxLength: 12,
    mediaRect: [512, 512]
  },
  formLabel: {
    input: '品牌名称'
  }

})
function toUploadBrand() {
  uploadModal.show = true;
}




const materialMax = 100;

const materialUploadMax = computed<number>(() => {
  const index = modal.materia_index;
  const material = modal.materia_form[index];
  return (materialMax - material.values.length) || 1;
})
// 媒体组件最多 ============
const mediaItemNumRange = computed(() => {
  // 自定义是最多1个 组件化创意最多15个
  if (creativor.value.isComponentCreative) {
    const ectypeMediaComponent = creativor.value.ectypeComponent['media'][0];
    return ectypeMediaComponent ? ectypeMediaComponent.max_group : 1;
  }
  return 1;
})
const remainAddMediaNum = computed(() => {
  return mediaItemNumRange.value - currentCreative.value.mediaComponent.length
});

function addGroup() {
  if (remainAddMediaNum.value <= 0) return;
  const media = creativor.value.ectypeComponent['media'][0];
  currentCreative.value.mediaComponent.push(media.clone())
}
function removeGroup(i: number) {

  currentCreative.value.mediaComponent.splice(i, 1)
}
// ===================

// 媒体组件最多 ============
const textItemNumRange = computed(() => {
  // 自定义是最多1个 组件化创意最多15个
  if (creativor.value.isComponentCreative) {
    const ectypeTextComponent = creativor.value.ectypeComponent['text'];
    return ectypeTextComponent ? ectypeTextComponent.max_group : 1;
  }
  return 1;
})
const remainAddTextNum = computed(() => {
  return textItemNumRange.value - currentCreative.value.textComponent.length
});

function addTextGroup() {
  if (remainAddTextNum.value <= 0) return;
  const text = creativor.value.ectypeComponent['text'];
  text && currentCreative.value.textComponent.push(text.clone())
}
function removeTexGroup(i: number) {
  currentCreative.value.textComponent.splice(i, 1)
}
// ===================

const modal = reactive<any>({
  max: 100,
  show: false,
  title: `批量添加素材(最多上传${materialMax}个素材)`,
  material: [],
  materia_form: [],
  materia_index: 0,
  creativeGroupNum: 1,
  creativeNum: 1,
  materialNum: 1,
});

const materialRules = computed(() => {
  const index = modal.materia_index;
  const material = modal.materia_form[index];
  if (creativor.value.unSpecifiedForm) {
    return {
      rect: [800],
      file_format: ['MOV', "MP4", "JPG", "JPEG", "PNG"],
      duration: [5, 300],
      suggest: [800, 800],
      size: (500 * 1024),
      ratio: [],
      max_number: 1
    }
  }
  const mediaComponent: any = creativor.value.ectypeComponent['media'][0];
  if (!mediaComponent) return {};
  const rules = material ? material.rules() : {};
  const array_property = mediaComponent.array_property || {};
  return {
    rect: [rules.min_width || rules.width || 500, rules.min_height || rules.height || 500],
    file_format: rules.file_format || [],
    duration: rules.min_duration || rules.max_duration ? [rules.min_duration, rules.max_duration] : [],
    suggest: rules.width || rules.height ? [rules.width, rules.height] : [],
    size: rules.file_size || (512000),
    ratio: rules.ratio_width ? [rules.ratio_width, rules.ratio_height] : [],
    max_number: array_property.max_number || 1

  }
});
const { validate: uploadValidate, createRequestMedia, uploadCover, accept, headers, uploadRef, rulesTips } = useUpload({
  rules: materialRules
})
const modalMaterialNum = computed(() => {
  const index = modal.materia_index;
  const material = modal.materia_form[index];
  return material.values.filter((_: any) => _.select).length

})

const currentMaterials = computed(() => {
  const index = modal.materia_index;
  const material = modal.materia_form[index];
  return material ? material.values : [];
})



const uploadParams = computed(() => {
  return {
    // action: 'https://upload.qiniup.com/',
    action: `/api/adgroup/${creativor.value.way}/upload`,
    data: {
      accountCode: account.value ? account.value.accountCode : undefined,
      adcreativeTemplateId: creativor.value.creativeTemplateId
    }
  }
});


function beforeUploadMaterial(fileInfo: any) {
  const file = Object.assign({}, fileInfo);
  file.loading = true;
  file.select = true;
  const index = modal.materia_index;
  const material = modal.materia_form[index];
  material.values.push(file);
}

function finishMaterialUpload(file: any) {
  const { id } = file;
  const index = modal.materia_index;

  const material = modal.materia_form[index];
  const i = material.values.findIndex((_: any) => _.id == id);

  material.values[i] = Object.assign({}, file, {
    select: true,
    loading: false
  })

  material.values = [].concat([], material.values);
  // 第0个为主素材，默认跟随第一个走
  modal.creativeGroupNum = Math.floor(material.values.length / (modal.materia_form[0].min || 1));
}

async function customRequest({
  file,
  onFinish
}: UploadCustomRequestOptions) {
  const info = await uploadValidate(file, undefined);
  if (!info) return;
  beforeUploadMaterial(info);
  const params = {
    accountCode: account.value ? account.value.accountCode : undefined,
    adcreativeTemplateId: creativor.value.creativeTemplateId
  }
  onFinish();
  const { data } = await http.uploadFiles({
    url: `/api/adgroup/${info.meta_type}/upload`,
    method: 'post',
    data: params
  }, file.file) as any;
  let media = Object.assign(createRequestMedia(data), info);
  media = await uploadCover(media, {
    accountCode: account.value ? account.value.accountCode : undefined,
  });
  finishMaterialUpload(media);
}



const currentCreativeGroupIndex = ref(0);
const currentCreativeGroup = computed<any>(() => {
  return creativor.value.groups[currentCreativeGroupIndex.value]
});

function removeCreativeGroup(i: number) {
  if (creativor.value.groups.length <= 1) return;
  creativor.value.groups.splice(i, 1);
  changeCreativeGroup(0);
}

function addCreativeGroup() {
  const newGroup = currentCreativeGroup.value.clone();
  creativor.value.groups.push(newGroup)
  currentCreativeGroupIndex.value = creativor.value.groups.length - 1;
}


function addCreative() {
  const newCreative = currentCreative.value.clone()
  currentCreativeGroup.value.creative.push(newCreative);
  currentCreativeIndex.value = currentCreativeGroup.value.creative.length - 1;

}
const currentCreativeIndex = ref(0);
const currentCreative = computed<any>(() => {
  return currentCreativeGroup.value.creative[currentCreativeIndex.value]
});
function removeCreative(i: number) {
  if (currentCreativeGroup.value.creative.length <= 1) return;
  currentCreativeGroup.value.creative.splice(i, 1);
  currentCreativeIndex.value = 0;

}

function changeCreativeGroup(id: number) {
  currentCreativeGroupIndex.value = id;
  currentCreativeIndex.value = 0;
}
function changeCreative(id: number) {
  currentCreativeIndex.value = id;
}

function handleShow() {
  // 首次注入 materia_form;
  const media = creativor.value.ectypeComponent['media'][0];
  if (media && !modal.materia_form.length) {
    modal.materia_form = media.materia_form();
  }
  // modal.materia_form = creativor.value.ectypeComponent['media'][0]
  modal.show = true;
}

function materialValidate() {
  const materia_form = modal.materia_form;
  const hasError = materia_form.find((materia: any) => {
    const uses = materia.values.filter((_: any) => _.select && !_.loading);
    if (uses.length % materia.min !== 0 || uses.length === 0) {
      return true;
    }
  });
  if (modal.creativeGroupNum == 0 || modal.creativeNum == 0) {
    message.warning(`请填写创意组以及创意个数!`)
    return false;
  }

  if (!modal.materialNum && creativor.value.isComponentCreative) {
    message.warning(`请填写每个创意的素材个数!`);
    return;
  }

  if (hasError) {
    message.warning(`创意形式的·${hasError.name}·要选择${hasError.min}的倍数的素材!`);
    return false;
  }

  return true;
}

function updateCreateGroup() {
  const vaidate = materialValidate();
  if (!vaidate) return;
  const uses: any = [];
  const unSpecifiedForm = creativor.value.unSpecifiedForm;
  modal.materia_form.map((materia: any) => {
    materia.values.filter((_: any) => {
      if (_.select) {
        uses.push(_)
      }
    })
  });
  // console.log(uses)
  modal.show = false;
  let _next = 0;
  const materialNum = modal.materialNum;
  new Array(modal.creativeGroupNum).fill(0).map(_ => {
    // 创建创意组
    const creativeGroup = currentCreativeGroup.value.clone();
    creativeGroup.creative = [];
    new Array(modal.creativeNum).fill(0).map(_ => {
      const creative = currentCreative.value.clone();
      // 不指定创意形式
      if (unSpecifiedForm) {
        creative.libMedia.empty();
        new Array(materialNum || 1).fill(0).map(_ => {
          const material = uses[_next] || {};
          const media = new MediaSingleComponent({}) as any;
          media.setSrc({
            keyFrameImageUrl: material.keyFrameImageUrl,
            meta_type: material.meta_type,
            media_id: material.media_id, media_url: material.media_url
          });
          _next = (_next === uses.length - 1) ? 0 : _next + 1;
          creative.libMedia.medias.push(media)
        })

      } else {
        creative.mediaComponent = new Array(materialNum || 1).fill(0).map(_ => {
          const media = creativor.value.ectypeComponent.media[0].clone();
          return media
        });
        // 创建创意
        const mediaComponent = creative.mediaComponent;
        mediaComponent.map((component: any) => {
          component.mediaMap((media: any) => {
            const material = uses[_next] || {};
            media.setSrc({
              keyFrameImageUrl: material.keyFrameImageUrl,
              meta_type: material.meta_type,
              media_id: material.media_id, media_url: material.media_url
            });
            _next = (_next === uses.length - 1) ? 0 : _next + 1;

          })

        })

      }



      creativeGroup.creative.push(creative);
    })
    creativor.value.groups.push(creativeGroup);
  })
}

function selectMaterial(item: any) {
  if (item.loading) return;
  item.select = !item.select;

}

watch(creativor.value.creativeTemplateId, () => {
  getAdDetail()
})


async function getAdDetail() {


}

function initAdDetail() {
  getAdDetail()
}


onBeforeMount(() => {
  initAdDetail()
})


const feedback = reactive({
  media: '',
  text: ''
});

function validateComponent(component: any, path: any) {
  // console.log(component, 'component');
  const isEmpty = (unref(component)).isEmpty();
  (feedback as any)[path] = isEmpty ? 'error' : '';
  return isEmpty;
}
const elementRef = ref();
const formRef = ref();
function validate() {
  return new Promise<void>((resolve, reject) => {
    formRef.value.validate((error: any) => {
      if (!error) {
        const marketComponents = adv.value.marketComponents;
        if (marketComponents['brand']) {
          if (creativor.value.brandType === 'WECHAT_CHANNELS') {
            const error = store.state.adv.accounts.find(account => !account.wechatChannels.id);
            if (error) {
              message.warning(`请配置全部账户的视频号!`)
              store.commit('adv/SCROLL_TO_ELEMENT', elementRef.value.$el)
              return reject();
            }
          }
        }
        const hasEmpty = creativor.value.groups.find((group, gi) => {
          const creative = group.creative.find((creative, ci) => {
            const media = creative.mediaComponent;
            const text = creative.textComponent;
            let hasEmpty = false;
            media.find((media: any) => {
              if (validateComponent(media, 'media')) {
                hasEmpty = true;
                return true;
              }

            });
            text.find((text: any) => {
              if (validateComponent(text, 'text')) {
                hasEmpty = true;
                return true;
              }
            })
            if (hasEmpty) {
              currentCreativeGroupIndex.value = gi;
              currentCreativeIndex.value = ci;
              return true;
            }
            return false;

          });
          if (creative) return true;
        });
        if (hasEmpty) {
          store.commit('adv/SCROLL_TO_ELEMENT', elementRef.value.$el)
          return reject();
        };
        resolve();
      } else {
        reject()
      }
    })
  })
}

defineExpose({
  validate
})



</script>
<style lang="scss">
.creative-content-material-upload-containter {
  .n-upload-trigger {
    width: 100% !important;
  }

}
</style>
<style lang="scss" scoped>
@import '@/assets/styles/var';



.creative-container {
  background-color: #FAFBFF;
  padding: 12px;
  border-radius: 3px;
}


.helper-tool {
  background: rgba(41, 107, 239, .06);
  border-radius: 6px;
  margin-right: 8px;

  // min-height: 90px;
  padding: 24px;
  padding-bottom: 10px;
}

.component-label {
  line-height: 22px;
  color: rgba(38, 38, 41, 0.72);
  font-weight: bold;
  margin-bottom: 10px;
}

.modal-image-group {}

.modal-image-card {
  height: 230px;
  width: 200px;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  position: relative;
  border: 1px solid #e6e8ed;
  background-color: rgba(41, 107, 239, 0.06);

  .icon-select {
    position: absolute;
    top: -1px;
    right: -1px;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-items: center;
    background-color: $primaryColor;
    text-align: center;
    justify-content: center;
    border-radius: 0 0 0 4px;
  }

  &.--active {
    border: 2px solid $primaryColor;

  }

  &.--loading {
    opacity: 0.3;
  }

  .image {
    flex: 1;
    width: 100%;
  }

  .desc {
    padding: 4px 8px;
  }
}

.modal-image-card+.modal-image-card {
  margin-left: 12px;
}
</style>
